
/**
  ******************************************************************************
  * Copyright 2021 The grapilot Authors. All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
  * @file       dev_mgr.h
  * @author     baiyang
  * @date       2021-10-20
  ******************************************************************************
  */

#pragma once

#ifdef __cplusplus
extern "C"{
#endif

/*----------------------------------include-----------------------------------*/
#include <stdint.h>
#include <stdbool.h>

#include <rtthread.h>
#include <rtdevice.h>
/*-----------------------------------macro------------------------------------*/
#define MHZ (1000U*1000U)
#define KHZ (1000U)

/* InertialSensor driver types */
#define HAL_INS_NONE         0
#define HAL_INS_MPU60XX_SPI  2
#define HAL_INS_MPU60XX_I2C  3
#define HAL_INS_HIL_UNUSED   4  // unused
#define HAL_INS_VRBRAIN      8
#define HAL_INS_MPU9250_SPI  9
#define HAL_INS_MPU9250_I2C 13
#define HAL_INS_MPU6500     19
#define HAL_INS_INV2_I2C    24
#define HAL_INS_INV2_SPI    25


/* Barometer driver types */
#define HAL_BARO_NONE        0
#define HAL_BARO_HIL_UNUSED  6  // unused
#define HAL_BARO_20789_I2C_I2C  14
#define HAL_BARO_20789_I2C_SPI  15
#define HAL_BARO_LPS25H_IMU_I2C 17

/* Compass driver types */
#define HAL_COMPASS_NONE                0
#define HAL_COMPASS_HIL_UNUSED          3  // unused

/* string names for well known SPI devices */
#define HAL_BARO_MS5611_NAME "ms5611"
#ifndef HAL_BARO_MS5611_SPI_INT_NAME
#define HAL_BARO_MS5611_SPI_INT_NAME "ms5611_int"
#endif
#define HAL_BARO_MS5611_SPI_EXT_NAME "ms5611_ext"
#define HAL_BARO_LPS22H_NAME "lps22h"
#define HAL_BARO_BMP280_NAME "bmp280"

#define HAL_INS_MPU60x0_NAME "mpu6000"
#define HAL_INS_MPU60x0_EXT_NAME "mpu6000_ext"

#define HAL_INS_LSM9DS0_G_NAME "lsm9ds0_g"
#define HAL_INS_LSM9DS0_A_NAME "lsm9ds0_am"

#define HAL_INS_LSM9DS0_EXT_G_NAME "lsm9ds0_ext_g"
#define HAL_INS_LSM9DS0_EXT_A_NAME "lsm9ds0_ext_am"

#define HAL_INS_MPU9250_NAME "mpu9250"
#define HAL_INS_MPU9250_EXT_NAME "mpu9250_ext"

#define HAL_INS_MPU6500_NAME "mpu6500"

#define HAL_INS_ICM20608_NAME "icm20608"
#define HAL_INS_ICM20608_AM_NAME "icm20608-am"
#define HAL_INS_ICM20608_EXT_NAME "icm20608_ext"

#define HAL_COMPASS_HMC5843_NAME "hmc5843"
#define HAL_COMPASS_LIS3MDL_NAME "lis3mdl"

#ifdef HAL_RTTHREAD_ARCH_FMUV2
#define ICM20608_SPI_DEVICE_NAME   "spi1_d4"
#define MPU9250_SPI_DEVICE_NAME    "spi1_d4"
#define MPU60x0_SPI_DEVICE_NAME    "spi1_d4"
#define L3GD20H_SPI_DEVICE_NAME    "spi1_d2"
#define MS5611_SPI_DEVICE_NAME     "spi1_d3"
#define LSM9DS0_SPI_DEVICE_NAME    "spi1_d1"
#define HMC5883_I2C_DEVICE_NAME    "i2c1"

#define ICM20608_SPI_DEVICE_ADDRESS   2U
#define MPU9250_SPI_DEVICE_ADDRESS    4U
#define MPU60x0_SPI_DEVICE_ADDRESS    4U
#define L3GD20H_SPI_DEVICE_ADDRESS    2U
#define MS5611_SPI_DEVICE_ADDRESS     3U
#define LSM9DS0_SPI_DEVICE_ADDRESS    1U

// spi1的ID是0
#define ICM20608_SPI_BUS_ID    0U
#define MPU9250_SPI_BUS_ID     0U
#define MPU60x0_SPI_BUS_ID     0U
#define L3GD20H_SPI_BUS_ID     0U
#define MS5611_SPI_BUS_ID      0U
#define LSM9DS0_SPI_BUS_ID     0U

// spi1的ID是0
#define ICM20608_SPI_SPEED_LOW    (4*MHZ)
#define ICM20608_SPI_SPEED_HIGH   (8*MHZ)

#define MPU9250_SPI_SPEED_LOW     (4*MHZ)
#define MPU9250_SPI_SPEED_HIGH    (8*MHZ)

#define MPU60x0_SPI_SPEED_LOW     (2*MHZ)
#define MPU60x0_SPI_SPEED_HIGH    (8*MHZ)

#define L3GD20H_SPI_SPEED_LOW     (3*MHZ)
#define L3GD20H_SPI_SPEED_HIGH    (3*MHZ)

#define MS5611_SPI_SPEED_LOW      (20*MHZ)
#define MS5611_SPI_SPEED_HIGH     (20*MHZ)

#define LSM9DS0_SPI_SPEED_LOW     (11*MHZ)
#define LSM9DS0_SPI_SPEED_HIGH    (11*MHZ)

#endif
/*----------------------------------typedef-----------------------------------*/
enum DeviceSpeed {
    DEV_SPEED_HIGH,
    DEV_SPEED_LOW,
};

struct DeviceStructure {
    uint8_t bus_type;  // rt_device_class_type
    uint8_t bus;       // which instance of the bus type
    uint8_t address;   // address on the bus (eg. I2C address)
    uint8_t devtype;   // device class specific device type
};

union DeviceId {
    struct DeviceStructure devid_s;
    uint32_t devid;
};

struct DeviceCallbackInfo{
    struct DeviceCallbackInfo *next;
    void (*cb)(void *parameter);
    void *parameter;
    uint32_t period_usec;
    uint64_t next_usec;
};

/*----------------------------------variable----------------------------------*/

/*-------------------------------------os-------------------------------------*/

/*----------------------------------function----------------------------------*/
rt_device_t devmgr_get_device(const char *name);
enum rt_device_class_type devmgr_get_device_type(rt_device_t device);
uint32_t devmgr_get_bus_id_devtype(rt_device_t dev, uint8_t devtype);
bool devmgr_set_speed(rt_device_t dev, enum DeviceSpeed speed);
bool devmgr_read_registers(rt_device_t dev, uint8_t first_reg, uint8_t *recv, uint32_t recv_len);
bool devmgr_write_register(rt_device_t dev, uint8_t reg, uint8_t val, bool checked);
struct DeviceCallbackInfo *devmgr_register_periodic_callback(rt_device_t dev, uint32_t period_usec, void (*cb)(void *parameter), void *parameter);
/*------------------------------------test------------------------------------*/

#ifdef __cplusplus
}
#endif



